/**
 * subMenu 组件
 */
import React, {
  useContext, useState, FC, Children, FunctionComponentElement,
  cloneElement, MouseEvent,
} from 'react';
import classNames from 'classnames';
import { MenuContext } from './menu';
import { IMenuItemProps } from './menuItem';
import Transition from '../Transition/transition';
import Icon from '../Icon/icon';

export interface ISubMenuProps {
  index?: string;
  title: string; // submenu title名 必须
  className?: string;
}

const SubMenu: FC<ISubMenuProps> = (props) => {
  const {
    index,
    title,
    className,
    children,
    ...rest
  } = props;

  const context = useContext(MenuContext);
  const openSubMenus = context.defaultOpenKeys as Array<string>;
  // 默认展开项
  const isOpeded = (index && context.mode === 'vertical') ? openSubMenus.includes(index) : false;

  const [menuOpen, setOpen] = useState(isOpeded);

  const classes = classNames('menu-item submenu-item', className, {
    'is-active': context.index === index,
    'is-opened': menuOpen,
    'is-vertical': context.mode === 'vertical',
  });

  // 点击事件 展开-关闭
  const handleClick = (e: MouseEvent) => {
    e.preventDefault();
    setOpen(!menuOpen);
  };

  let timer: any;
  // 鼠标事件 展开还是关闭
  const handleMouse = (e: MouseEvent, toggled: boolean) => {
    clearTimeout(timer);
    e.preventDefault();
    // 演示展示
    timer = setTimeout(() => {
      setOpen(toggled);
    }, 300);
  }

  // 纵向布局 submenu onclick 展开子节点
  const clickEvents = context.mode === 'vertical' ? {
    onClick: handleClick,
  } : {};

  // 横向布局 submenu hover效果 展开子节点
  const hoverEvents = context.mode !== 'vertical' ? {
    onMouseEnter: (e: MouseEvent) => {handleMouse(e, true)},
    onMouseLeave: (e: MouseEvent) => {handleMouse(e, false)},
  } : {};

  /**
   * 渲染子节点，并想子节点 menu-item 传递属性
   * @returns 
   */
  const renderChildren = () => {
    const subMenuClasses = classNames('submenu', {
      'menu-opened': menuOpen,
    });

    const childrenComponent = Children.map(children, (child, i) => {
      const childElement = child as FunctionComponentElement<IMenuItemProps>;
      if(childElement.type.displayName !== 'MenuItem'){
        console.error('Warning: SubMenu has a child which is not a MenuItem component');
        return null;
      }
      return cloneElement(childElement, {
        index: `${index}-${i}`,
      });;
    });

    return (
      <Transition
        in={menuOpen}
        timeout={300}
        animation="zoom-in-top"
      >
        <ul className={subMenuClasses}>
          {childrenComponent}
        </ul>
      </Transition>
    )
  };

  return (
    <li
      key={index}
      className={classes}
      {...hoverEvents}
      {...rest}
    >
      <div
        className="submenu-item"
        {...clickEvents}
      >
        {title}
        <Icon icon="angle-down" className="arrow-icon" />
      </div>
      {renderChildren()}
    </li>
  )
};

SubMenu.displayName = "SubMenu";

export default SubMenu;